﻿/*                       NOTICE
 * 
 * This software was produced for the U. S. Government
 * under Contract No. FA8721-10-C-0001, and is
 * subject to the Rights in Noncommercial Computer Software
 * and Noncommercial Computer Software Documentation Clause
 * (DFARS) 252.227-7014 (JUN 1995)
 * 
 * Approved for Public Release: 11-2435
 * © 2011 The MITRE Corporation. All Rights Reserved. 
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using System.Drawing;
using System.Reflection;

using GestureListenerClient.Services.Delegates;

namespace GestureListenerClient.Services
{
    public class ListenerRegistration
    {
        /// <summary>
        /// Create a new listener to look for gesture events
        /// </summary>
        /// <param name="name">Name of this listener</param>
        /// <param name="captureBounds">Coordinates on the UI to capture in</param>
        /// <param name="callBackDel">Delegate to call when gesture occurs</param>
        public ListenerRegistration(string name, RectangleF captureBounds, GestureCallbackDelegate callBackDel)
        {
            this.Name = name;
            this.CaptureBounds = captureBounds;
            this.CallbackDelegate = callBackDel;
        }

        public ListenerRegistration(string name, RectangleF captureBounds, FiducialCallbackDelegate callBackDel)
        {
            this.Name = name;
            this.CaptureBounds = captureBounds;
            this.FiducialCallbackDelegate = callBackDel;
        }

        public string Name { get; set; }
        public RectangleF CaptureBounds { get; set; }
        public GestureCallbackDelegate CallbackDelegate { get; set; }
        public FiducialCallbackDelegate FiducialCallbackDelegate { get; set; }

        /// <summary>
        /// Does the listener care about a specific gesture? Does it fall in the capture bounds? Is it the gesture type we want?
        /// </summary>
        /// <param name="gesture">Geseture to inspect</param>
        /// <returns>True if we want it, false otherwise</returns>
        public bool caresAboutGesture(Gestures.Gesture gesture)
        {
            bool caresAboutGest = true;
            //Check to see if it falls in the bounds they're observing
            foreach (PointF point in gesture.Coords)
            {
                if (!CaptureBounds.Contains(point))
                {
                    caresAboutGest = false;
                    break;
                }
            }
            if (caresAboutGest)
            {
                if (CallbackDelegate != null)
                {
                    EventInfo[] properties = CallbackDelegate.GetType().GetEvents();
                    foreach (EventInfo property in properties)
                    {
                        try
                        {
                            //TODO: BROKEN
                            var test = CallbackDelegate.eventMap[gesture.GetType()];
                            Type callbackType = CallbackDelegate.eventMap.Single(x => x.Value.Equals(property)).Key;
                            if (callbackType.Equals(gesture.GetType()))
                            {
                                caresAboutGest = true;
                                break;
                            }
                        }
                        catch (Exception)
                        { //Element doesn't exist... we don't care}
                        }

                    }

                }
                else
                {
                    EventInfo[] properties = FiducialCallbackDelegate.GetType().GetEvents();
                    foreach (EventInfo property in properties)
                    {
                        try
                        {
                            //TODO: BROKEN
                            var test = FiducialCallbackDelegate.eventMap[gesture.GetType()];
                            Type callbackType = FiducialCallbackDelegate.eventMap.Single(x => x.Value.Equals(property)).Key;
                            if (callbackType.Equals(gesture.GetType()))
                            {
                                caresAboutGest = true;
                                break;
                            }
                        }
                        catch (Exception)
                        { //Element doesn't exist... we don't care}
                        }

                    }
                }
            }
            return caresAboutGest;
        }

        public override bool Equals(object obj)
        {
            if (obj is ListenerRegistration && obj != null)
            {
                ListenerRegistration otherListener = obj as ListenerRegistration;
                if (CallbackDelegate != null)
                {
                    return (CaptureBounds.Equals(otherListener.CaptureBounds) && CallbackDelegate.Equals(otherListener.CallbackDelegate));
                }
                else
                {
                    return (CaptureBounds.Equals(otherListener.CaptureBounds) && FiducialCallbackDelegate.Equals(otherListener.FiducialCallbackDelegate));
                }
            }
            else return base.Equals(obj);
        }
    }
}
